#include "decryptFile.h"
#include "sha1.h"
#include "aes.h"

int hexaRepToBytes(unsigned char * src, unsigned char dest[], int srcSize);
void doXor(unsigned char * dest, unsigned char * src, int length);
int tryDecrypt(char * userName, unsigned char
	hexaBytes[AESKEYLENGTH], FILE * encFile, FILE * respFile, dictioStruct * dictionary);

int
decryptFile(userElem user, FILE * encFile, FILE * respFile, dictioStruct * dictionary)
{
	unsigned char hexaBytes[AESKEYLENGTH];

	//transformo la clave del archivo de claves a formato de bytes
	if (!hexaRepToBytes(user.key, hexaBytes, HEXASTRLEN))
	{
		printf("Error en el vuelco hexadecimal de %s\n", user.name);
		return -1;
	}

	//devuelve el texto desencriptado o NULL si no se logro desencriptar
	return tryDecrypt(user.name, hexaBytes, encFile, respFile, dictionary);
}

int
tryDecrypt(char * userName, unsigned char hexaBytes[AESKEYLENGTH],
	FILE * encFile, FILE * respFile, dictioStruct * dictionary)
{
	unsigned char aesKey[AESKEYLENGTH];
	int resp = -1;
	char userKey[MAXKEYLENGTH + 1];

	//itero mientras no encuentre una respuesta y queden claves para adivinar
	//en userKey me queda la posible clave
	while ( resp != 1 && getKey(dictionary, userKey) == 1 )
	{
		//deja la respuesta en aesKey, que en realidad no es la clave de aes
		//hasta que se le aplique en xor mas abajo
		calculateSha1(userName, userKey, aesKey);

		//en aesKey me queda la posible clave para desencriptar aes
		doXor(aesKey, hexaBytes, AESKEYLENGTH);
//		printf("usuario %s y clave %s\n", userName, userKey);
		resp = decryptAES(encFile, respFile, aesKey);
	}

	if (resp == 1)
		printf("Con el usuario %s y la clave %s", userName, userKey);

	return resp;
}

unsigned char
charToHexa(unsigned char c)
{
	unsigned char resp;
	if (isalpha(c))
		resp = toupper(c) - 'A' + 10;
	else
		resp = c - '0';

	return resp;
}

void
printHexa(unsigned char * bytes, int length)
{
	int j;

	for (j = 0; j < length; j++)
	{
		printf("%02X ", bytes[j]);
	}
	putchar('\n');
}

//devuelve 0 si fallo
int
hexaRepToBytes(unsigned char * src, unsigned char dest[], int srcSize)
{
	int destSize = srcSize / 2;
	int i;

	for (i = 0; i < destSize; i++)
	{
		if (isxdigit(src[i*2]) == 0 || isxdigit(src[i*2+1] == 0))
			return 0;

		//primero armo la mitad menos significativa
		dest[i] = charToHexa(src[i*2+1]);
		//y despues armo la mas significativa
		dest[i] += (charToHexa(src[i*2]) << 4);
	}

	return 1;
}

void
doXor(unsigned char * dest, unsigned char * src, int length)
{
	if (dest == NULL || src == NULL || length <= 0)
		return;

	int i;
	for (i = 0; i < length; i++)
	{
		dest[i] = dest[i] ^ src[i];
	}
}
